package me.numark;

import com.android.volley.Request.Method;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

import butterknife.ButterKnife;
import butterknife.InjectView;
import me.numark.model.LogInResponse;
import me.numark.net.BaseResponse;
import me.numark.net.GsonRequest;
import me.numark.net.NetworkConstants;
import me.numark.net.NetworkHelper;
import me.numark.utils.Constants;
import me.numark.utils.Settings;
import me.numark.utils.Utils;

/**
 * Created by tian on 14-9-20:下午9:56.
 */
public class RegisterActivity extends AuthenticatorActivity implements OnClickListener {

    @InjectView(R.id.back)
    ImageView back;

    @InjectView(R.id.title)
    TextView title;

    @InjectView(R.id.right_text)
    TextView rightText;

    @InjectView(R.id.mobile_edit)
    EditText mobileEdit;

    @InjectView(R.id.get_verify_code_button)
    Button getVerifyCodeButton;

    @InjectView(R.id.verify_code_edit)
    EditText verifyCodeEdit;

    @InjectView(R.id.nick_edit)
    EditText nickEdit;

    @InjectView(R.id.password_edit)
    EditText passwordEdit;

    @InjectView(R.id.verify_password_edit)
    EditText verifyPasswordEdit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        ButterKnife.inject(this);
        back.setOnClickListener(this);
        title.setText(R.string.register);
        rightText.setText(R.string.next_step);
        rightText.setOnClickListener(this);
        getVerifyCodeButton.setOnClickListener(this);
        mobileEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                getVerifyCodeButton.setEnabled(s != null && s.length() == 11);
            }
        });
    }

    private CountdownHandler mHandler = new CountdownHandler(this);

    private static final int MSG_COUNT_DOWN = 30;

    private static final int MSG_COUNT_DOWN_BEGIN = 31;

    private static final int MSG_COUNT_DOWN_FINISHED = 32;

    private int countDown = Constants.SMS_COUNT_DOWN_TIME;

    private static class CountdownHandler extends Handler {

        WeakReference<RegisterActivity> mActivityRef;

        public CountdownHandler(RegisterActivity activity) {
            super();
            mActivityRef = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            RegisterActivity activity = mActivityRef.get();
            if (activity == null) {
                return;
            }

            switch (msg.what) {
                case MSG_COUNT_DOWN:
                    activity.getVerifyCodeButton.setEnabled(false);
                    sendEmptyMessage(MSG_COUNT_DOWN);
                    break;
                case MSG_COUNT_DOWN_BEGIN:
                    activity.countDown--;
                    activity.getVerifyCodeButton.setText(
                            String.format(activity.getString(R.string.count_down_time_left),
                                    activity.countDown));
                    if (activity.countDown > 0) {
                        sendEmptyMessageDelayed(MSG_COUNT_DOWN, 1000);
                    } else {
                        sendEmptyMessage(MSG_COUNT_DOWN_FINISHED);
                    }
                    break;
                case MSG_COUNT_DOWN_FINISHED:
                    activity.getVerifyCodeButton.setText(R.string.get_verify_code);
                    activity.getVerifyCodeButton.setEnabled(true);
                    activity.countDown = Constants.SMS_COUNT_DOWN_TIME;
                    break;
            }
        }
    }

    private void finishCountdown() {
        countDown = 0;
        mHandler.removeMessages(MSG_COUNT_DOWN);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.back:
                finish();
                break;
            case R.id.right_text:
                if (isInputValid()) {
                    doRegister();
                }
                break;
            case R.id.get_verify_code_button:
                getVerifyCode();
                break;
        }
    }

    private boolean isInputValid() {
        boolean ret = true;
        if (TextUtils.isEmpty(verifyCodeEdit.getText().toString())) {
            verifyCodeEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_wrong, 0);
            ret = false;
        } else {
            verifyCodeEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_right, 0);
        }
        if (TextUtils.isEmpty(nickEdit.getText().toString())) {
            nickEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_wrong, 0);
            ret = false;
        } else {
            nickEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_right, 0);
        }
        if (isValidPassword()) {
            passwordEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_right, 0);
        } else {
            passwordEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_wrong, 0);
            ret = false;
        }
        if (isValidPassword2()) {
            verifyPasswordEdit
                    .setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_right, 0);
        } else {
            verifyPasswordEdit
                    .setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_wrong, 0);
            ret = false;
        }
        return ret;
    }

    static final String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{7,16}$";

    private boolean isValidPassword() {
        String pwd = passwordEdit.getText().toString();
        return !(TextUtils.isEmpty(pwd) || !pwd.matches(regex));
    }

    private boolean isValidPassword2() {
        String pwd = passwordEdit.getText().toString();
        String pwd2 = verifyPasswordEdit.getText().toString();
        return !TextUtils.isEmpty(pwd2) && pwd2.equals(pwd);
    }

    private void getVerifyCode() {
        final String mobile = mobileEdit.getText().toString();
        mHandler.sendEmptyMessage(MSG_COUNT_DOWN_BEGIN);
        GsonRequest<BaseResponse> request = new GsonRequest<>(
                NetworkConstants.REGISTER_URL + "?cellphone=" + mobile,
                Method.GET, BaseResponse.class, false, null, new Listener<BaseResponse>() {
            @Override
            public void onResponse(BaseResponse response) {
                dismissProgress();
                if (response.ret) {
                    Utils.showToast(R.string.get_verify_code_success);
                } else {
                    Utils.showToast(response.msg);
                }
            }
        }, new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                dismissProgress();
                Utils.showToast(R.string.generic_network_error);
            }
        });
        NetworkHelper.getInstance().getRequestQueue().add(request);
        NetworkHelper.getInstance().getRequestQueue().start();
        showProgress();
    }

    private void doRegister() {
        Map<String, String> params = new HashMap<>();
        params.put("cellphone", mobileEdit.getText().toString());
        params.put("code", verifyCodeEdit.getText().toString());
        params.put("nick", nickEdit.getText().toString());
        params.put("password", passwordEdit.getText().toString());
        GsonRequest<LogInResponse> request = new GsonRequest<>(NetworkConstants.REGISTER_URL,
                Method.POST, LogInResponse.class, false, params, new Listener<LogInResponse>() {
            @Override
            public void onResponse(LogInResponse response) {
                dismissProgress();
                if (response.ret) {
                    finishCountdown();
                    Settings.saveMobile(mobileEdit.getText().toString());
                    Settings.saveUid(Integer.toString(response.data.uid));
                    Settings.saveToken(response.data.token);
                    Settings.saveNick(nickEdit.getText().toString());
                } else {
                    Utils.showToast(response.msg);
                }
            }
        }, new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                dismissProgress();
                Utils.showToast(R.string.generic_network_error);
            }
        });
        NetworkHelper.getInstance().getRequestQueue().add(request);
        NetworkHelper.getInstance().getRequestQueue().start();
        showProgress();
    }
}
